package co.fitstart.admin.handler.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.demo2do.core.BusinessException;

import co.fitstart.admin.handler.QrcodeHandler;
import co.fitstart.admin.handler.support.FileStorage;
import co.fitstart.entity.order.Order;
import co.fitstart.entity.user.User;

/**
 * 
 * @author lidan
 *
 */
@Component("qrcodeHandler")
public class QrcodeHandlerImpl implements QrcodeHandler {
    
    private static final Logger logger = LoggerFactory.getLogger(QrcodeHandlerImpl.class);
    
    @Value("#{config['file.upload.path']}")
    private String uploadPath;
    
    /**
     * 
     * @param user
     * @return
     */
    private boolean validateUser(User user) {
        
        if(user.getWechat() == null || StringUtils.isEmpty(user.getWechat().getCode()) || StringUtils.isEmpty(user.getWechat().getQrcode())) {
            logger.trace("user wechat code or wechat qrcode not exit, do not save qrcode into order package");
            return false;
        }
        
        if(user.getUserFit() == null || user.getUserFit().getHeight() == null || user.getUserFit().getWeight() == null || user.getUserFit().getBmiValue() == null) {
            logger.trace("user fit weight height bmi not exit, do not save qrcode into order package");
            return false;
        }
        
        return true;
    }
    
    /**
     * 
     * @param order
     * @param user
     * @return
     */
    private FileStorage generateOrderFileStorage(Order order, User user) {
        
        // delete old qrcode first
        String filename = org.apache.commons.lang3.StringUtils.replace(order.getProduct().getName(), " ", "-");
        
        String filePath = filename + "/" +
                "[" + order.getOrderStatus().getDescription() + "-" + order.getPaymentStatus().getDescription() + "]" + filename + "_" + 
                user.getName() + "_" + user.getWechat().getCode() + "_" + 
                user.getUserFit().getHeight() + "_" + user.getUserFit().getWeight() + "_" + user.getUserFit().getBmiValue();
        
        logger.info("generateOrderFileStorage# generate fileStorage with fileName [{}] and filePath [{}]", filename, filePath);
        FileStorage fileStorage = new FileStorage(filePath, user.getMobile(), "jpg");
        
        return fileStorage;
    }
    
    /**
     * 
     * @param user
     * @return
     */
    private InputStream getUserQrcodeFile(User user) {
        
        InputStream inputStream;
        
        try {
            
            String wechatCode = user.getWechat().getCode();
            String fileName = org.apache.commons.lang3.StringUtils.replace(wechatCode, " ", "-");
            fileName = StringUtils.replace(fileName, ".", "-");
            
            logger.info("#getUserQrcodeFile() start get user qrcode file with fileName[{}]", fileName);
            
            File qrcode = new File(uploadPath + "/user/qrcode/" + fileName, fileName + ".jpg");
            inputStream = new FileInputStream(qrcode);
            
        } catch (FileNotFoundException e) {
            logger.error("#getUserQrcodeFile() error");
            throw new BusinessException("获取用户二维码失败");
        }
        
        return inputStream;
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.admin.handler.QrcodeHandler#saveUserQrcode(java.lang.String, java.lang.String)
     */
    public String saveUserQrcode(String code, String mediaId) {

//        // get qrcode inputstream from 
//        InputStream inputStream = tencentHandler.downloadResource(mediaId);
//        
//        // generate qrcode name and path
//        String wechatCode = profileInvestigation.getWechatCode();
//        String fileName = org.apache.commons.lang3.StringUtils.replace(wechatCode, " ", "-");
//        fileName = StringUtils.replace(fileName, ".", "-");
//        
//        // save inputstream into file with floder and path
//        FileStorage fileStorage = new FileStorage("/user/qrcode/" + fileName, fileName + ".jpg");
//        fileHandler.save(fileStorage, inputStream);
        
        return null;
    }
    
    /* (non-Javadoc)
     * @see co.fitstart.mobile.handler.FileHandler#save(co.fitstart.mobile.entity.FileStorage, java.io.InputStream)
     */
    public void saveOrderQrcode(Order order, User user) {
        
        // validate user could save order qrcode or not
        if(!this.validateUser(user)) {
            throw new BusinessException("用户数据异常");
        }
        
        // get qrocde inputStream from user by params user
        InputStream inputStream = this.getUserQrcodeFile(user);
        
        // generate order qrcode fileStorage
        FileStorage fileStorage = this.generateOrderFileStorage(order, user);
        
        // save order qrcode into file
        this.save(fileStorage, inputStream);
    }

    /*
     * (non-Javadoc)
     * @see co.fitstart.admin.handler.QrcodeHandler#deleteOrderQrcode(co.fitstart.entity.order.Order, co.fitstart.entity.user.User)
     */
    public boolean deleteOrderQrcode(Order order, User user) {
        
        // get filepath which will be deleted
        FileStorage fileStorage = this.generateOrderFileStorage(order, user);
        String filePath = fileStorage.getPath();
        
        // do delete
        boolean result = this.delete(filePath);
        if(result) {
            logger.info("deleteOrderQrcode success");
        }else {
            logger.info("deleteOrderQrcode# failed");
        }
        
        return result;
    }
    
    /**
     * 
     * @param fileStorage
     * @param inputStream
     * @return
     */
    protected String save(FileStorage fileStorage, InputStream inputStream) {

        // 1. 新建文件 （新建文件名为系统指定文件名，扩展名为源文件扩展名， 路径为指定路径）
        File file = new File(this.uploadPath + fileStorage.getPath(), fileStorage.getFileName());
        
        // 2. 将字节流copy到新文件
        try {
            FileUtils.copyInputStreamToFile(inputStream, file);
        } catch (IOException e) {
            logger.error("#save() error");
            throw new BusinessException("文件存储失败");
        }
        
        // 3. 返回文件路径 + 文件名 + 扩展名
        return fileStorage.getFileName();
    }
    
    /**
     * 
     * @param filePath
     * @return
     */
    protected boolean delete(String filePath) {
        File file = FileUtils.getFile(uploadPath + filePath);
        return FileUtils.deleteQuietly(file);
    }
}
